Skip to content

Add Dedicated IPs#87

Open
tuckerchapin wants to merge 4 commits into
mainfrom
tucker/dedicated-ips
Open

Add Dedicated IPs#87
tuckerchapin wants to merge 4 commits into
mainfrom
tucker/dedicated-ips

Conversation

@tuckerchapin
Copy link
Copy Markdown
Contributor

  • Poll-on-Create until status=RUNNING as provisioning is async
  • environment_ids is a Set with Default(empty set) so empty/absent/null/[] are all equivalent and dashboard drift produces a plan diff rather than being silently absorbed
  • region is RequiresReplace as we don't support region changes.
  • Cassette-based acceptance tests cover create → rename + description update → switch to env-scoped → switch back to workspace-scoped → destroy, plus separate import-flow and data-source tests.
  • Cassettes were Recorded against the test workspace using evm-d81p...cn1g as the literal env ID in testdata/env_scoped.tf (don't change without re-recording).
  • The regen bundles some unrelated upstream types (sandboxes/storage/envvar subpackages, etc.).

Pulls in new types/endpoints added since the last regen (sandboxes,
storage, artifactsources; new DeployMode, CacheProfile, EndShellEvent
enums; named client.Region replacing inline string; webservice Plan
replacing PaidPlan; renamed StreamTaskRunsEventsParamsAccept enum
const). Updates the keyvalue, postgres, redis and webservice resources
with the small downstream type casts these renames require.

No feature changes — pure plumbing to unblock the next commit.
Exposes Render's Dedicated IP product via Terraform: workspace- or
environment-scoped egress IPs that services in the same region route
outbound traffic through. CRUD against /dedicated-ips, ImportState
passthrough on the egs- ID.

Provisioning is asynchronous on the API side. Create polls (up to 15
minutes) until status transitions from CREATING/PENDING to RUNNING so
the computed ips attribute is populated when apply returns. Matches
the postgres resource's poll-on-create pattern.

environment_ids is a Set with a Default(empty set), making omit, null,
and [] equivalent and making the attribute strictly TF-authoritative —
drift from the dashboard surfaces as a plan diff rather than being
silently absorbed into state.

Includes acceptance tests covering the create / rename / env-scope
toggle / import flow plus a data-source test. Cassettes are recorded
against a live Render workspace; see resource_test.go for the
re-record command.

The underlying REST endpoints are still x-internal in the public
OpenAPI; a separate api-repo PR will drop those flags before this
lands.
Recorded against production with the test workspace and a real
environment ID (evm-d81pghf7f7vs73bocn1g) for env_scoped.tf. Replay is
deterministic; no live credentials needed for re-running. Owner ID
and Authorization are scrubbed via the standard testhelpers hooks.
Picks up changes landed in api repo master since the previous regen:
- envvar.yaml component file (envVars in workflows create endpoint)
- ArtifactSource EnvId → Runtime field rename
- Other minor type/operation updates across events, webhooks, workflows

- `created_at` (String) Time the dedicated IP was created.
- `id` (String) Unique identifier for this dedicated IP.
- `ips` (List of String) The IPv4 addresses assigned to this dedicated IP. Empty until provisioning completes (when status is RUNNING).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it mean for multiple IPs to be assigned to a single IP?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How long does provisioning take? I think my expectation with Terraform is that a resource will block on apply until it's fully ready, rather than return a "RUNNING" status.

Comment on lines +86 to +89
// Provisioning is asynchronous. POST returns immediately with
// status=CREATING and ips=[]; status transitions to RUNNING once the
// EgressGatewaySet's Elastic IPs are allocated. Poll until then so
// computed attributes (ips, status) are populated when apply returns.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we do wait! Is "RUNNING" just a status we'd expect from a data source, then, and not a resource?

Comment on lines +13 to +26
// TestDedicatedIPResource exercises the full lifecycle: workspace-scoped
// create → rename + description update → switch to environment-scoped →
// switch back to workspace-scoped. Each step also asserts that the ID
// stays stable (no recreate) and that the `ips` computed attribute is
// populated after polling.
//
// To re-record this cassette, edit testdata/env_scoped.tf to reference
// a real environment ID from the workspace used for recording, then run:
//
// RENDER_HOST=https://api.render.com/v1 \
// RENDER_OWNER_ID=tea-<workspace-id> \
// RENDER_API_KEY=<key> \
// UPDATE_RECORDINGS=true TF_ACC=1 \
// go test ./internal/provider/dedicatedip/resource/... -v -timeout 60m
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very helpful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants